#include "media_sys.h"

int jiesu = 0;
bool Show_Progress_Bar(MEDIA_POI mp, int progress) 
{
    if (mp == NULL || progress < 0 || progress > 100) {
        printf("参数错�??！\n");
        return false;
    }

    // 进度条背�?????颜色
    int bg_color = 0x00ffffff; 
    // 进度条前�?????颜色
    int fg_color = 0x00ff0000; 
    // 进度条位�?????和大�?????
    int bar_x = 100;
    int bar_y = 400;
    int bar_width = 600;
    int bar_height = 50;

    Show_bmp("1.bmp",200,50);
    //绘制进度条背�?????
    for (int x = bar_x; x < bar_x + bar_width; x++) 
    {
        for (int y = bar_y; y < bar_y + bar_height; y++) 
        {
            *(mp->mmap_start_poi + mp->lcd_w * y + x) = bg_color;
        }
    }

    //计算进度条当前长�?????
    int current_width = (bar_width * progress) / 100;

    // 绘制进度条前�?????
    for (int x = bar_x; x < bar_x + current_width; x++) 
    {
        for (int y = bar_y; y < bar_y + bar_height; y++) 
        {
            *(mp->mmap_start_poi + mp->lcd_w * y + x) = fg_color;
        }
    }

    return true;
}


//投图�?????
bool Show_bmp(const char * bmp_path,int seat_x,int seat_y)
{
    int fd = open("/dev/fb0", O_RDWR);
    if (fd == -1)
    {
        perror("open...");
        return false;
    }
    
    unsigned int * lcd_ptr = (int *)mmap(NULL, 
                                        800*480*4, 
                                        PROT_READ | PROT_WRITE, 
                                        MAP_SHARED, 
                                        fd, 
                                        0
                                        );
    if (lcd_ptr == MAP_FAILED)
    {
        perror("mmap...");
        return false;
    }

    int *new_p = lcd_ptr + seat_y*800 + seat_x;
    int bmp_fd = open(bmp_path, O_RDONLY);
    if (bmp_fd == -1)
    {
        perror("open...");
        return false;
    }
    int bmp_w,bmp_h,skip;
    lseek(bmp_fd, 18, SEEK_SET);
    if (read(bmp_fd, &bmp_w, 4) == -1)
    {
        perror("read...");
        return false;
    }

    if (read(bmp_fd, &bmp_h, 4) == -1)
    {
        perror("read...");
        return false;
    }

    if (bmp_w* 3 % 4 != 0)
    {
        bmp_w += bmp_w*3  % 4;
    }
    
    lseek(bmp_fd, 54, SEEK_SET);

    char rgb[bmp_w * bmp_h *3];
    if (read(bmp_fd, rgb, bmp_w * bmp_h *3) == -1)
    {
        perror("read...");
        return false;
    }

	int x, y, n;
	for(y=0,n=0; y<bmp_h; y++)
	{
		for(x=0; x<bmp_w; x++,n+=3)
		{
			*(new_p+(bmp_h-1-y)*800+x) = rgb[n]<<0 | rgb[n+1]<<8  |rgb[n+2]<<16;
		}
        //n += skip;
	}
    

    if (munmap(lcd_ptr, 800*480*4) == -1)
    {
        perror("munmap...");
        return false;
    }

    if (close(fd) == -1)
    {
        perror("close...");
        return false;
    }

    if (close(bmp_fd) == -1)
    {
        perror("close...");
        return false;
    }
    
    
    return true;
}   

// //�????文显�????
// void* word_display_thread(void* arg)
// {
//     char  buf[] = "ͼƬ������Ϊ";
    
//     int where_x = 500;
//     int where_y = 10;
//     while(1)
//     {
//         where_x = 500;
//         where_y = 10;
//         for(int i = 0; i < strlen(buf); i+=2)
//         {
//             if (Chinese_Show(&buf[i], where_x, where_y) == false)
//             {
//                 printf("error\n");
//                 return false;
//             }
            
//             where_x += 16; // 每个字�?��?�度�?????16像素
//         }
//         if (jiesu == 1)
//         {
//             break;
//         }
        
//     }

//     return NULL;
// }

//构建线程显示时间
void* time_display_thread(void* arg)
{
    int year = 2025;
    int month = 5;
    int day = 12;
    int hour = 18;
    int min = 48;
    int second = 1;
    // 创建格式化的时间字�?�串
    char time_str[40];
    int where_x = 10;
    int where_y = 10;
    while(1)
    {
        // 显示格式化后的字符串
        where_x = 10;
        where_y = 10;
        sprintf(time_str, "%04d-%02d-%02d %02d:%02d:%02d", 
        year, month, day, hour, min, second);
        for(int i = 0; i < strlen(time_str); i++)
        {
            if (Char_Show(time_str[i], where_x, where_y) == false)
            {
                printf("error\n");
                return false;
            }
            
            where_x += 16; // 每个字�?��?�度�?????16像素
        }
        second++;
        if (second == 60)
        {
            min+=1;
            second = 0;
        }
        if (min == 60)
        {
            hour+= 1;
            min  = 0;
        }
        if (hour == 24)
        {
            day += 1;
            hour = 0; 
        }
        if (day == 30)
        {
            month +=1;
            day = 1;
        }
        if (month > 12)
        {
            year += 1;
            month = 1;
        }
        sleep(1);

        if (jiesu == 1)
        {
            break;
        }
    }
    return NULL;
}


MEDIA_POI Media_Sys_Init()//项目初�?�化  初�?�化
{

    MEDIA_POI mp = (MEDIA_POI)malloc(sizeof(MEDIA_STR));
    if(mp == (MEDIA_POI)NULL)
    {
        perror("malloc ...");
        return (MEDIA_POI)-1;
    }

    memset(mp,0,sizeof(MEDIA_STR));

    //初�?�化LCD�?????件资�?????
    if((mp->lcd = open(LCD_DEV_PATH,O_RDWR)) == -1)
    {
        perror("open ...");
        return (MEDIA_POI)-1;
    }

    //获取LCD �????? w �????? h
    struct fb_var_screeninfo var;
    //ioctl 获取 fB0对应的LCD 的�?�和�?????
    if(ioctl(mp->lcd,FBIOGET_VSCREENINFO,&var) == -1)
    {
        perror("ioctl ...");
        return (MEDIA_POI)-1;
    }
    else
    {
        mp->lcd_w = var.xres;
        mp->lcd_h = var.yres;
        printf("LCDw:%d----LCDh:%d\n",mp->lcd_w,mp->lcd_h);
    }


    // 根据显存大小去映�?????
    if((mp->mmap_start_poi = (int *)mmap(NULL,mp->lcd_w*mp->lcd_h*LCD_PIXEL_SIZE,PROT_READ | PROT_WRITE,MAP_SHARED,mp->lcd,0)) == (int *)MAP_FAILED)
    {
        perror("mmap ...");
        return (MEDIA_POI)-1;
    }

    //初�?�化触摸屏硬件资�?????
    if((mp->ts = open(TOUCH_LCD_DEV_PATH,O_RDONLY)) == -1)
    {
        perror("open ...");
        return (MEDIA_POI)-1;
    }

    mp->touch_x = -1;
    mp->touch_y = -1;

    //在这里显示主界面

    if(Show_Ui(mp,"/tmp/main_ui.bmp") == false)
    {
        printf("显示主界面失败！\n");
        return (MEDIA_POI)-1;
    }
    return mp;
}

// 主界面显示函�?????
bool Show_Ui(MEDIA_POI mp, const char *ui_pic_path)
{
    // 打开图片文件
    int bmp = open(ui_pic_path, O_RDONLY);
    if (bmp == -1)
    {
        perror("open...");
        return false;
    }
    // 获取图片的�?�和�?????
    int bmp_w, bmp_h;
    if (lseek(bmp, 18, SEEK_SET) == -1)
    {
        perror("lseek 18...");
        return false;
    }

    if (read(bmp, &bmp_w, sizeof(int)) == -1)
    {
        perror("read bmp_w...");
        return false;
    }

    if (read(bmp, &bmp_h, sizeof(int)) == -1)
    {
        perror("read bmp_h...");
        return false;
    }

    int skip = 0;
    if (bmp_w * BMP_PIXEL_SIZE % 4 != 0)
    {
        skip = 4 - (bmp_w * BMP_PIXEL_SIZE % 4);
    }

    // 根据宽和高去定义数组的大�?????
    char rgb[bmp_w * bmp_h * BMP_PIXEL_SIZE + skip * bmp_h];

    // 读取图片的像素点
    if (lseek(bmp, 54, SEEK_SET) == -1)
    {
        perror("lseek 54 ...");
        return false;
    }

    if (read(bmp, rgb, bmp_w * bmp_h * BMP_PIXEL_SIZE + skip * bmp_h) == -1)
    {
        perror("read bmp rgb ...");
        return false;
    }
    
    for (int y = 0, n = 0; y < bmp_h; y++)
    {
        for (int x = 0; x < bmp_w; x++, n += 3)
        {
            *(mp->mmap_start_poi + mp->lcd_w * (bmp_h - 1 - y) + x) = \
                rgb[n] << 0 | 
                rgb[n + 1] << 8 | 
                rgb[n + 2] << 16;
        }

        n += skip;
    }

    // 关闭图片文件
    if (close(bmp) == -1)
    {
        perror("close ui bmp ...");
        return false;
    }

    return true;
}


//单个文字显示
bool Chinese_Show(char * font,int where_x,int where_y)
{
    int * new_lcd_mmap = CSI.lcd_mmap_poi_w + 800*where_y+where_x;
    int font_offset = (94*(font[0]-0xa0-1)+font[1]-0xa0-1)*32;
    char * font_obj_p = CSI.dzk_mmap_poi_w + font_offset;

    for(int y=0; y<16; y++)
    {
        for(int x=0; x<2; x++)
        {
            char type = *(font_obj_p+2*y+x);            
            for(int z=0; z<8; z++)    
            {                                           
                if(type & 0x80>>z) 
                {
                    *(new_lcd_mmap + 800*y+(8*x+z)) = CSI.font_color;

                }
                else
                {
                    *(new_lcd_mmap + 800*y+(8*x+z)) = CSI.broadground_color;

                }
            }
        }
    }
    return true;
}

bool Word_Show_Init(unsigned int font_color,unsigned int broadground_color)//字体显示初�?�化
{
    /*
        1）打开fb0进�?�映�?????  
        2）打开Dzk文件获取DZK文件大小并且进�?�映射，映射空间�?????就有汉字库的字模数据了�?
    */

    if((CSI.lcd_w = open(LCD_DEV_PATH,O_RDWR)) == -1)
    {
        perror("open lcd ...");
        return false;
    }

    if((CSI.lcd_mmap_poi_w = (int *)mmap(NULL,800*480*4,PROT_READ|PROT_WRITE,MAP_SHARED,CSI.lcd_w,0)) == MAP_FAILED)
    {
        perror("mmap lcd ...");
        return false;
    }


    if((CSI.dzk_w = open(DZK_CHINESE_PATH,O_RDWR)) == -1)
    {
        perror("open dzk... ");
        return false;
    }

    if((CSI.dzk_file_size_w = lseek(CSI.dzk_w,0,SEEK_END)) == -1)
    {
        perror("lseek dzk ...");
        return false;
    }

    if(lseek(CSI.dzk_w,0,SEEK_SET) == -1)
    {
        perror("lseek dzk ...");
        return false;
    }

    if((CSI.dzk_mmap_poi_w = (char *)mmap(NULL,CSI.dzk_file_size_w,PROT_READ|PROT_WRITE,MAP_SHARED,CSI.dzk_w,0)) == MAP_FAILED)
    {
        perror("mmap lcd ...");
        return false;
    }

    //设置字体颜色 �????? 背景颜色
    CSI.font_color        = font_color;
    CSI.broadground_color = broadground_color;

    return true;
}

//文字的初始化
bool Chinese_Show_Init(unsigned int font_color,unsigned int broadground_color)//字体显示初�?�化
{
    /*
        1）打开fb0进�?�映�?????  
        2）打开Dzk文件获取DZK文件大小并且进�?�映射，映射空间�?????就有汉字库的字模数据了�?
    */

    if((CSI.lcd = open(LCD_DEV_PATH,O_RDWR)) == -1)
    {
        perror("open lcd ...");
        return false;
    }

    if((CSI.lcd_mmap_poi = (int *)mmap(NULL,800*480*4,PROT_READ|PROT_WRITE,MAP_SHARED,CSI.lcd,0)) == MAP_FAILED)
    {
        perror("mmap lcd ...");
        return false;
    }


    if((CSI.dzk = open(DZK_DEV_PATH,O_RDWR)) == -1)
    {
        perror("open dzk... ");
        return false;
    }

    if((CSI.dzk_file_size = lseek(CSI.dzk,0,SEEK_END)) == -1)
    {
        perror("lseek dzk ...");
        return false;
    }

    if(lseek(CSI.dzk,0,SEEK_SET) == -1)
    {
        perror("lseek dzk ...");
        return false;
    }

    if((CSI.dzk_mmap_poi = (char *)mmap(NULL,CSI.dzk_file_size,PROT_READ|PROT_WRITE,MAP_SHARED,CSI.dzk,0)) == MAP_FAILED)
    {
        perror("mmap lcd ...");
        return false;
    }

    //设置字体颜色 �????? 背景颜色
    CSI.font_color        = font_color;
    CSI.broadground_color = broadground_color;

    return true;
}

//单个字�?�的显示
bool Char_Show(char  char_data,int where_x,int where_y)//
{

    int *new_mmap_poi = CSI.lcd_mmap_poi + 800 * where_y + where_x;
    int font_offset  = char_data * 32;
    char * font_obj_p = CSI.dzk_mmap_poi + font_offset;

    for(int y=0; y<16; y++) //表示16�?????
    {
        for(int x=0; x<2; x++) //每�?�有2�?????字节,这循�?????两�?�，每�?�只获取一�?????字节的__字模数据____
        {
            //获取一�?????字节的字模数�????? 
            char type = *(font_obj_p+2*y+x);            
            for(int z=0; z<8; z++) //每一�?????字节 8 �?????     
            {                                           
                if(type & 0x80>>z) //0x80就是二进制的10000000
                {
                    //字体颜色
                    *(new_mmap_poi + 800*y+(8*x+z)) = CSI.font_color;

                }
                else
                {
                    //背景颜色
                    *(new_mmap_poi + 800*y+(8*x+z)) = CSI.broadground_color;

                }
            }
        }
    }

    return true;
}

bool Get_Touch_Xy(MEDIA_POI mp)//获取触摸屏坐�?????
{
    struct input_event touch;
    while(1)
    {
        if(read(mp->ts,&touch,sizeof(touch)) == -1)
        {
            perror("read touch lcd ...");
            return false;
        }

        if(touch.type == EV_ABS && touch.code == ABS_X) mp->touch_x = touch.value * mp->lcd_w / 1024;
        if(touch.type == EV_ABS && touch.code == ABS_Y) mp->touch_y = touch.value * mp->lcd_h / 600;
        
        if(touch.type == EV_KEY && touch.code == BTN_TOUCH && touch.value == 0)
        {
            break;
        }

    }

    return true;
}


bool Main_Touch_Ctrl(MEDIA_POI mp)//主界面触摸控�?????
{

    while(1)
    {
        //先获取点击的触摸坐标，再去判�?????坐标�?????�?????�?????按钮的区�?????
        if(Get_Touch_Xy(mp) == false)
        {
            printf("读取触摸屏坐标失败！\n");
            return false;
        }

        if(mp->touch_x > 31 && mp->touch_x < 293 && mp->touch_y > 271 && mp->touch_y < 424) //相册按钮
        {
            if(Album(mp) == false)
            {
                printf("�?????动相册失败！\n");
                return false;
            }
        }

        if(mp->touch_x > 486 && mp->touch_x < 749 && mp->touch_y > 271 && mp->touch_y < 424) //游戏按钮
        {
            if(Game(mp) == false)
            {
                printf("�?????动游戏失败！\n");
                return false;
            }
        }

        if(mp->touch_x > 683 && mp->touch_x < 773 && mp->touch_y > 30 && mp->touch_y < 200) //退出按�?????
        {
            mp->touch_x = -1;
            mp->touch_y = -1;
            
            break;
        }
    }

    return true;
}


bool Lcd_Clean(MEDIA_POI mp,int color) //刷指定�?�色全屏
{
    for(int y=0; y<mp->lcd_h; y++)
    {
        for(int x=0; x<mp->lcd_w; x++)
        {
            *(mp->mmap_start_poi + mp->lcd_w * y + x) = color;
        }
    }

    return true;
}


bool Media_Sys_Free(MEDIA_POI mp)//项目结束释放 --- �?????件�?��?�结束释�?????
{
    jiesu = 1;
    //显示退出界�?????
    if(Show_Ui(mp,"/tmp/exit_ui.bmp") == -1)
    {
        printf("显示退出界面失败！\n");
        return false;
    }
    if(close(mp->lcd) == -1)
    {
        perror("close ...");
        return false;
    }

    if(close(mp->ts) == -1)
    {
        perror("close ...");
        return false;
    }

    if(munmap(mp->mmap_start_poi,mp->lcd_w * mp->lcd_h * LCD_PIXEL_SIZE) == -1)
    {
        perror("munmap ...");
        return false;
    }

    free(mp);
    
    return true;
}